﻿// 2023/3/8: 首个版本
// 2023/9/22: 使用PassParent给ShowDialog传参
// 2023/9/25: 改为直接输入Icon对象
// 2023/10/9: 添加英文注释

using System;
using System.IO;
using System.Xml;
using System.Text;
using Eto.Forms;
using Eto.Drawing;
using ASEva;
using ASEva.Samples;
using ASEva.UIEto;

namespace CommonSource
{
    class GlobalValuesEditor : DialogPanel
    {
        public GlobalValuesEditor(Icon icon = null)
        {
            Icon = icon;
            Title = chinese ? "全局值一览" : "Global Values";
            SetResizableMode(900, 500, 900, 500);

            var tabControl = this.SetContentAsColumnLayout().AddControl(new TabControl(), true) as TabControl;
            var paramPage = tabControl.AddPage(chinese ? "全局参数" : "Parameters");
            var pathPage = tabControl.AddPage(chinese ? "全局路径" : "Paths");
            var varPage = tabControl.AddPage(chinese ? "全局变量" : "Variables");

            initParamPage(paramPage, icon);
            initPathPage(pathPage);
            initVarPage(varPage);
        }

        private void initParamPage(TabPage page, Icon icon)
        {
            var mainLayout = page.SetContentAsRowLayout(8, 8, VerticalAlignment.Stretch);
            var list = mainLayout.AddControl(new ListBox(), false, 250) as ListBox;
            var valueLayout = mainLayout.AddColumnLayout(true, 2);
            var titleLayout = valueLayout.AddRowLayout();
            titleLayout.AddLabel(chinese ? "参数值:" : "Parameter Value:");
            titleLayout.AddSpace();
            var linkXML = titleLayout.AddLinkButton(chinese ? "按XML编辑" : "Edit as XML");
            var linkEdit = titleLayout.AddLinkButton(chinese ? "编辑" : "Edit");
            var linkSave = titleLayout.AddLinkButton(chinese ? "保存" : "Save");
            var textArea = valueLayout.AddControl(new TextArea{ Enabled = false }, true) as TextArea;
            linkXML.Enabled = linkEdit.Enabled = linkSave.Enabled = false;

            list.SelectedIndexChanged += delegate
            {
                var val = Agency.GetGlobalParameter(list.SelectedKey, "");
                if (val == null) val = "";
                String niceXmlString = null;
                bool isXml = checkIsXml(val, out niceXmlString);

                linkEdit.Enabled = true;
                linkXML.Enabled = isXml;
                textArea.Text = isXml ? niceXmlString : val;
            };

            linkXML.Click += delegate
            {
                var val = Agency.GetGlobalParameter(list.SelectedKey, "");
                if (String.IsNullOrEmpty(val)) return;

                var dialog = new XmlEditor(val, icon);
                App.RunDialog(dialog);
                if (dialog.BoolResult)
                {
                    textArea.Text = dialog.XmlString;
                    Agency.SetGlobalParameter(list.SelectedKey, dialog.XmlString);
                }
            };

            linkEdit.Click += delegate
            {
                list.Enabled = false;
                linkXML.Enabled = linkEdit.Enabled = false;
                linkSave.Enabled = true;
                textArea.Enabled = true;
            };

            linkSave.Click += delegate
            {
                list.Enabled = true;
                linkEdit.Enabled = true;
                linkSave.Enabled = false;
                textArea.Enabled = false;

                Agency.SetGlobalParameter(list.SelectedKey, textArea.Text);

                String niceXmlString = null;
                bool isXml = checkIsXml(textArea.Text, out niceXmlString);
                linkXML.Enabled = isXml;
                if (isXml) textArea.Text = niceXmlString;
            };

            foreach (var key in Agency.GetGlobalParameterKeys())
            {
                list.Items.Add(key, key);
            }
            if (list.Items.Count > 0) list.SelectedIndex = 0;
        }

        private void initPathPage(TabPage page)
        {
            var mainLayout = page.SetContentAsRowLayout(8, 8, VerticalAlignment.Stretch);
            var list = mainLayout.AddControl(new ListBox(), false, 250) as ListBox;
            var valueLayout = mainLayout.AddColumnLayout(true, 2);
            var titleLayout = valueLayout.AddRowLayout();
            titleLayout.AddLabel(chinese ? "路径:" : "Paths:");
            titleLayout.AddSpace();
            var linkRemove = titleLayout.AddLinkButton(chinese ? "移除" : "Remove");
            var linkDir = titleLayout.AddLinkButton(chinese ? "添加文件夹" : "Add folder");
            var linkFile = titleLayout.AddLinkButton(chinese ? "添加文件" : "Add file");
            var listPath = valueLayout.AddControl(new ListBox(), true) as ListBox;
            linkDir.Enabled = linkFile.Enabled = false;

            list.SelectedIndexChanged += delegate
            {
                var val = Agency.GetGlobalPath(list.SelectedKey);
                if (val == null) val = "";
                var paths = val.Split(';', StringSplitOptions.RemoveEmptyEntries);

                linkDir.Enabled = linkFile.Enabled = true;
                listPath.Items.Clear();
                foreach (var path in paths) listPath.Items.Add(path);
            };

            linkRemove.Click += delegate
            {
                if (listPath.SelectedIndex >= 0)
                {
                    listPath.Items.RemoveAt(listPath.SelectedIndex);
                    Agency.SetGlobalPath(list.SelectedKey, String.Join(';', listPath.Items));
                }
            };

            linkDir.Click += delegate
            {
                var val = Agency.GetGlobalPath(list.SelectedKey);
                if (val == null) val = "";

                var dialog = new SelectFolderDialog();
                dialog.Directory = Directory.Exists(val) ? val : "";
                if (dialog.ShowDialog(App.PassParent(this)) == DialogResult.Ok)
                {
                    listPath.Items.Add(dialog.Directory);
                    Agency.SetGlobalPath(list.SelectedKey, String.Join(';', listPath.Items));
                }
            };

            linkFile.Click += delegate
            {
                var val = Agency.GetGlobalPath(list.SelectedKey);
                if (val == null) val = "";

                var dialog = new OpenFileDialog();
                dialog.FileName = File.Exists(val) ? val : "";
                if (dialog.ShowDialog(App.PassParent(this)) == DialogResult.Ok)
                {
                    listPath.Items.Add(dialog.FileName);
                    Agency.SetGlobalPath(list.SelectedKey, String.Join(';', listPath.Items));
                }
            };

            foreach (var key in Agency.GetGlobalPathKeys())
            {
                list.Items.Add(key, key);
            }
            if (list.Items.Count > 0) list.SelectedIndex = 0;
        }

        private void initVarPage(TabPage page)
        {
            var mainLayout = page.SetContentAsRowLayout(8, 8, VerticalAlignment.Stretch);
            var list = mainLayout.AddControl(new ListBox(), false, 250) as ListBox;
            var valueLayout = mainLayout.AddColumnLayout(true, 2);
            valueLayout.AddLabel(chinese ? "变量值:" : "Variable Value:");
            var textArea = valueLayout.AddControl(new TextArea{ Enabled = false }, true) as TextArea;

            list.SelectedIndexChanged += delegate
            {
                var val = Agency.GetGlobalVariable(list.SelectedKey, "");
                if (val == null) val = "";
                if (val.Length > 1000000) val = val.Substring(0, 1000000); // A maximum of one million is displayed / 最多显示一百万左右
                String niceXmlString = null;
                bool isXml = checkIsXml(val, out niceXmlString);
                textArea.Text = isXml ? niceXmlString : val;
            };

            foreach (var key in Agency.GetGlobalVariableKeys())
            {
                list.Items.Add(key, key);
            }
            if (list.Items.Count > 0) list.SelectedIndex = 0;
        }

        private bool checkIsXml(String str, out String niceXmlString)
        {
            niceXmlString = "";
            if (str == null) str = "";
            if (str.StartsWith("<?xml"))
            {
                var xml = new XmlDocument();
                try
                {
                    xml.LoadXml(str);
                    niceXmlString = toNiceString(xml);
                    return true;
                }
                catch (Exception) {}
            }
            return false;
        }

        private String toNiceString(XmlDocument xml)
        {
            if (xml == null) return "";

            var memoryStream = new MemoryStream();

            var settings = new XmlWriterSettings();
            settings.Indent = true;
            settings.IndentChars = "    ";

            var xmlWriter = XmlWriter.Create(memoryStream, settings);
            xml.Save(xmlWriter);
            xmlWriter.Close();

            memoryStream.Position = 3; // BOM
            var data = new byte[memoryStream.Length - 3];
            memoryStream.Read(data, 0, (int)memoryStream.Length - 3);
            memoryStream.Close();

            return Encoding.UTF8.GetString(data);
        }

        private bool chinese = Agency.GetAppLanguage() == "ch";
    }
}